package com.iisigroup.http.test;
 
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.ClassUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair; 
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse; 
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.robert.study.utils.POIUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.poi.ss.usermodel.WorkbookFactory;

import tw.gov.moi.ris.aw.webapply.doorplate.constants.SearchType;
import tw.gov.moi.ris.aw.webapply.doorplate.dto.DoorplateSearchDTO;
 

/**
 * 村里街路門牌查詢 ( 以部分街路門牌查詢 )
 * （資料庫是在jdbc:informix-sqli://140.92.86.177:4526/lportal:informixserver=ibm;NEWCODESET=utf8,8859-1,819;DB_LOCALE=en_us.8859-1;CLIENT_LOCALE=en_us.8859-1;IFX_USE_STRENC=true
 * 表格是在 awdf020m  ）
 * 參考https://hc.apache.org/httpcomponents-client-4.3.x/quickstart.html
 * 而做出來的測試程式碼
 */
public class App7 extends BaseCommonHttpMethod{
    private final static int num =2;
    private final static Logger LOGGER = LoggerFactory.getLogger(App7.class);
    private final static String captchaKeyRegExpress = ".*<input\\D*type=\"hidden\"\\D*name=\"captchaKey\"\\D*value=\"(.*)\".*\\/>.*";
    private final static String captchaKeycheckRegExpress = ".*<input\\D*type=\"hidden\"\\D*name=\"lastCaptchaKey\"\\D*value=\"(.*)\".*\\/>.*";
    private final static String tktRegExpress = ".*<input\\D*id=\"tkt\"\\D*name=\"tkt\"\\D*type=\"hidden\"\\D*value=\"(.*)\".*\\/>.*";
    static List<String[]> srcData;
    
    public static void main(String[] args) throws Exception { 
    	srcData =  getPseudoData();
        if(ArrayUtils.isNotEmpty(args)){
        	File personIdFile = new File(args[0]);
        	if(personIdFile==null && !personIdFile.exists()){
        		System.out.println(String.format("%s does not exist ! ", args[0]));        		
        	}else {
        		System.out.println(String.format("use file %s ! ", args[0]));      
        	 
        	}
        }
//        		while (true) {
//        ResponseResult rr = new App7().testMethod();
//        LOGGER.info("average time: {}",String.valueOf((rr.getAverageTime())/ 1.0e3)) ;
//        LOGGER.info("非預期結果比數 :{}",rr.getWrongValidationRec().size()) ;
//        LOGGER.info("-----------------------") ;
        
//        		}
        		new App7().multiProcess();
    }
    public void setBlank(final Serializable dto){

   	 final PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(dto.getClass());
   	 for(final PropertyDescriptor property : propertyDescriptors){    		
   		 if( ClassUtils.isAssignable( property.getPropertyType(), String.class)   && property.getWriteMethod() != null){
   			 final String attributeName = property.getName();
   			 try {
					 PropertyUtils.setProperty(dto, attributeName,"");
					 
				} catch (Exception e) {
					LOGGER.error(e.getMessage() ,e );
				}
   		 }
   	 }
    }
    public UrlEncodedFormEntity fromDto(final Serializable dto ,final String tkt){
    	 final List<NameValuePair> nvps = new ArrayList<NameValuePair>(); 
    	 
    	 final PropertyDescriptor[] propertyDescriptors = PropertyUtils.getPropertyDescriptors(dto.getClass());
    	 for(final PropertyDescriptor property : propertyDescriptors){    		
    		 if( ClassUtils.isAssignable( property.getPropertyType(), String.class) ||  ClassUtils.isAssignable( property.getPropertyType(), SearchType.class)){
    			 final String attributeName = property.getName();
    			 try {
					final Object tmp = PropertyUtils.getProperty(dto, attributeName);
					 final String value  = tmp!=null ? tmp.toString():"";
					 nvps.add(new BasicNameValuePair(attributeName,value));
				} catch (Exception e) {
					LOGGER.error(e.getMessage() ,e );
				}
    		 }
    	 }
       nvps.add(new BasicNameValuePair("tkt",tkt));
       nvps.add(new BasicNameValuePair("page","1"));
//       nvps.add(new BasicNameValuePair("rows","20"));
       nvps.add(new BasicNameValuePair("rows","100"));
    	 final Charset  charset =  Charset.forName("UTF-8");
         //必須指定參數為 UTF-8 編碼
         final  UrlEncodedFormEntity entity =  new UrlEncodedFormEntity(nvps, charset);
         return entity ; 
    }
    public DoorplateSearchDTO retrieveQuery(){
    	final DoorplateSearchDTO result = new DoorplateSearchDTO();
    	result.setAreaCode("65000120");
    	result.setCityCode("65000000");
    	result.setSearchType(SearchType.doorplate);
    	result.setVillage("龍川");
    	result.setNeighbor("");
    	result.setStreet("一坑路");
    	result.setSection("");
    	result.setLane("");
    	result.setAlley("");
    	result.setNumber("");
    	result.setNumber1("");
    	result.setFloor("");
    	result.setExt("");
//         nvps.add(new BasicNameValuePair("tkt",tkt));
//         nvps.add(new BasicNameValuePair("page","1"));
//         nvps.add(new BasicNameValuePair("rows","20"));
    	
    	return result ; 
    }
    public ResponseResult testMethod() throws ClientProtocolException, IOException { 
//    	final String ip = "192.168.9.22";
//    	final String port ="8080";
    	final String port ="5703";
//    	final String ip = "192.168.10.18";
    	final String ip = "140.92.86.177";
    	final String templateUrl0 = "http://%s:%s/apply/app/doorplate/map?searchType=doorplate#";
    	final String templateUrl = "http://%s:%s/apply/app/doorplate/query";
    	final String doorplateQueryTemplateUrl = "http://%s:%s/apply/app/doorplate/doorplateQuery"; 
        final long times = 1l;
        final ResponseResult result = new ResponseResult();
        long totalTime = 0l;
         
        
        for (int c = 0; c < times; c++) {
        	try {
                Thread.sleep(ThreadLocalRandom.current().nextInt(10000));
            } catch (final InterruptedException e) {
                LOGGER.error(e.getMessage(), e);
            }
        	boolean isRight = (c%2==0);
        	final long startTime = System.currentTimeMillis();
            final CloseableHttpClient httpclient = getHttpClient(null,0);
            final String startUrl = String.format(templateUrl0, ip,port);
            final String url = String.format(templateUrl, ip,port);
            final String doorplateQueryUrl =String.format(doorplateQueryTemplateUrl, ip,port);
            final HttpGet httpGet = new HttpGet(startUrl);
            final CloseableHttpResponse response1 = httpclient.execute(httpGet);
            final HttpEntity entity1 = response1.getEntity();
            final String initContent = EntityUtils.toString(entity1);
//            System.out.println(initContent);
            
            final HttpPost httpPost0 = new HttpPost(url);
            final List<NameValuePair> nvps0 = new ArrayList<NameValuePair>();
            nvps0.add(new BasicNameValuePair("cityCode","65000000"));
            nvps0.add(new BasicNameValuePair("searchType","doorplate"));
            httpPost0.setEntity(new UrlEncodedFormEntity(nvps0)); 
            CloseableHttpResponse response0 = null;
            String tkt ="";
            try {
            	response0 = httpclient.execute(httpPost0); 
            	
                final String responseStatus = response0.getStatusLine().toString().intern();
                result.getListResult().add(responseStatus.toString().intern());
                //LOGGER.info(responseStatus);
                final HttpEntity entity2 = response0.getEntity();
                final String content = EntityUtils.toString(entity2);
//                System.out.println(content);
                tkt =  extractTkt(content);
                EntityUtils.consume(entity2);
                
            }  finally {
            	if(response0!=null){
            		response0.close();
            	}
            }
             
            final HttpPost httpPost = new HttpPost(doorplateQueryUrl);
            
//            final DoorplateSearchDTO query =  retrieveQuery();
            final DoorplateSearchDTO query =   getRandomDoorplateSearchDTO(srcData);
            
//            System.out.println( ToStringBuilder.reflectionToString(query));
            
            final  UrlEncodedFormEntity newEntity =   fromDto(query, tkt);
            httpPost.setEntity(newEntity); 
            CloseableHttpResponse response2 = null;

            try {
            	
            	response2 = httpclient.execute(httpPost); 
            	 
            	
                final String responseStatus = response2.getStatusLine().toString().intern();
                result.getListResult().add(responseStatus.toString().intern());
                //LOGGER.info(responseStatus);
                final HttpEntity entity2 = response2.getEntity();
                final String content = EntityUtils.toString(entity2);
                if(StringUtils.contains(content, "</html>")){
//                	 System.out.println(content);
                	 System.out.println( ToStringBuilder.reflectionToString(query));
                	;
                }else{
//                	 System.out.println(content);
                }
//           	 System.out.println(content);
                
                
                final Header[] allHeaders = response2.getAllHeaders();
//                for(Header aHeader : allHeaders){
//                	LOGGER.info("name:{} ,value:{}" ,aHeader.getName(),aHeader.getValue());                	
//                }
               
                EntityUtils.consume(entity2);
//                final List<String> urlList2 = urlResources(ip);
//                getResponseByGet(httpclient, urlList2.toArray(new String[]{}));
            } catch (final Exception e) {
                System.out.println("ERR:" + e.toString());
            } finally {
            	if(response2!=null){
            		response2.close();
            	}
            }
            final long intervalTime = System.currentTimeMillis() - startTime;
            totalTime += intervalTime;
            httpclient.close();
            LOGGER.info("{}",intervalTime);
            
        }
        result.setAverageTime(totalTime / times);

        //如果要測試戶籍員的反應...則要把httpclient.close();註解掉,這樣才會使得stuck thread 不會消失
        return result;
    }
   
   
    
     public List<String> urlResources(final String ip){
    	 List<String> result = new ArrayList<String>();
    	 result.add( String.format("https://%s/js/jquery-easyui-1.3.1/jquery-1.7.2.min.js", ip));
    	 result.add( String.format("https://%s/js/jquery-easyui-1.3.1/jquery.easyui.min.js", ip));
    	 result.add( String.format("https://%s/js/jquery-easyui-1.3.1/locale/easyui-lang-zh_TW.js", ip));
    	 result.add( String.format("https://%s/js/jquery-easyui-1.3.1/themes/default/easyui.css", ip));
    	 result.add( String.format("https://%s/js/jquery-easyui-1.3.1/themes/icon.css", ip));
    	 result.add( String.format("https://%s/js/swUtils.js", ip));
    	 result.add( String.format("https://%s/js/blockui/jquery.blockUI.js", ip));
    	 result.add( String.format("https://%s/images/logo.swf", ip));
    	
    	 return result;    	
     }   
     @Override
 	int getThreadNum() {
 		return num;
 	}
     private String extractTkt(final String content){
     	return extractString(content, tktRegExpress);
     }
     private String extractLastCaptchaKey(final String content){
     	return  extractString(content, captchaKeycheckRegExpress);
     }
     private String extractCaptchaKey(final String content){
     	return  extractString(content, captchaKeyRegExpress);
     }
     public static  List<String[]> getPseudoData(){
    	 final	InputStream is = App7.class.getResourceAsStream("awdf020m_sample.xls");
    	 try {
			final	Workbook wb = WorkbookFactory.create(is);
			 org.apache.poi.ss.usermodel.Sheet sheet = wb.getSheet("awdf020m");
			 Row header = sheet.getRow(0);			 
			 int headerNumberOfCells = header.getPhysicalNumberOfCells();// 得到column數目
			 List<String[]> initData = POIUtils.processFromSheet(sheet);
			 LOGGER.info("{}",initData.size()  );
			 return initData;
		} catch (Exception e) {
			 LOGGER.error(e.getMessage(), e  );
		} finally{
			if(is !=null ){
				try {
					is.close();
				} catch (IOException e) {
					 LOGGER.info(e.getMessage(), e  );
				}
			}
		}
    	 return null;
     }
    public DoorplateSearchDTO getRandomDoorplateSearchDTO(final List<String[]> srcData){
    	final DoorplateSearchDTO result = new DoorplateSearchDTO();
    	setBlank(result);
    	result.setSearchType(SearchType.doorplate);
    	if(CollectionUtils.isNotEmpty(srcData)){
    		final int index = ThreadLocalRandom.current().nextInt(srcData.size());
    		final String[] line = srcData.get(index);
    		result.setAlley(line[12]);
    		result.setAreaCode(line[3]);
    		String siteId = line[0];
    		String cityCode = siteId.substring(0, 5)+"000";
    		result.setCityCode(cityCode);
    		result.setNeighbor(line[6]);
    		
    		final String street = line[8];
    		final String partialStreet =street.length() >0 ? StringUtils.left(street, ThreadLocalRandom.current().nextInt(street.length())):"";
    		final String village = line[5]; 
    		final String partialVillage = village.length() >0 ?StringUtils.left(village, ThreadLocalRandom.current().nextInt(village.length())):"";
    		result.setStreet(partialStreet);
    		result.setVillage(partialVillage);
    		
    	}
    	return result;
    }
     
}
